import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Exclude, Expose, Transform, Type } from 'class-transformer';

export class ParticipantResponseDto {
  @ApiProperty({ description: '参与者ID' })
  @Expose()
  id: string;

  @ApiProperty({ description: '用户ID' })
  @Expose()
  userId: string;

  @ApiProperty({ description: '用户昵称' })
  @Expose()
  nickname?: string;

  @ApiProperty({ description: '用户头像URL' })
  @Expose()
  avatar?: string;

  @ApiProperty({ description: '参与者角色' })
  @Expose()
  role: 'host' | 'participant';

  @ApiProperty({ description: '连接状态' })
  @Expose()
  status: 'connecting' | 'connected' | 'disconnected' | 'reconnecting';

  @ApiProperty({ description: '音频状态' })
  @Expose()
  audioEnabled: boolean;

  @ApiProperty({ description: '视频状态' })
  @Expose()
  videoEnabled: boolean;

  @ApiProperty({ description: '屏幕共享状态' })
  @Expose()
  screenShareEnabled: boolean;

  @ApiProperty({ description: '是否静音' })
  @Expose()
  isMuted: boolean;

  @ApiPropertyOptional({ description: '网络质量信息' })
  @Expose()
  networkQuality?: {
    rtt?: number;
    packetLoss?: number;
    bandwidth?: number;
    quality?: 'excellent' | 'good' | 'fair' | 'poor';
    lastUpdated?: Date;
  };

  @ApiProperty({ description: '加入时间' })
  @Expose()
  joinedAt: Date;

  @ApiPropertyOptional({ description: '离开时间' })
  @Expose()
  leftAt?: Date;

  @ApiProperty({ description: '最后活动时间' })
  @Expose()
  lastActivityAt: Date;

  @ApiProperty({ description: '是否在线' })
  @Expose()
  @Transform(
    ({ obj }) => obj.status === 'connected' || obj.status === 'reconnecting',
  )
  isOnline: boolean;

  @ApiProperty({ description: '是否为主持人' })
  @Expose()
  @Transform(({ obj }) => obj.role === 'host')
  isHost: boolean;

  @ApiProperty({ description: '显示名称' })
  @Expose()
  @Transform(({ obj }) => obj.nickname || obj.userId)
  displayName: string;

  // 隐藏敏感信息
  @Exclude()
  socketId: string;

  @Exclude()
  ipAddress: string;

  @Exclude()
  userAgent: string;

  @Exclude()
  roomId: string;

  @Exclude()
  createdAt: Date;

  @Exclude()
  updatedAt: Date;
}

export class RoomResponseDto {
  @ApiProperty({ description: '房间ID' })
  @Expose()
  id: string;

  @ApiPropertyOptional({ description: '房间名称' })
  @Expose()
  name?: string;

  @ApiPropertyOptional({ description: '房间描述' })
  @Expose()
  description?: string;

  @ApiProperty({ description: '创建者ID' })
  @Expose()
  creatorId: string;

  @ApiProperty({ description: '最大参与者数量' })
  @Expose()
  maxParticipants: number;

  @ApiProperty({ description: '当前参与者数量' })
  @Expose()
  currentParticipants: number;

  @ApiProperty({ description: '房间状态' })
  @Expose()
  status: 'waiting' | 'active' | 'ended';

  @ApiProperty({ description: '是否需要密码' })
  @Expose()
  requiresPassword: boolean;

  @ApiPropertyOptional({ description: '房间配置' })
  @Expose()
  settings?: {
    audioEnabled?: boolean;
    videoEnabled?: boolean;
    screenShareEnabled?: boolean;
    chatEnabled?: boolean;
    recordingEnabled?: boolean;
  };

  @ApiProperty({ description: '房间过期时间' })
  @Expose()
  expiresAt: Date;

  @ApiProperty({ description: '最后活动时间' })
  @Expose()
  lastActivityAt: Date;

  @ApiProperty({ description: '创建时间' })
  @Expose()
  createdAt: Date;

  @ApiProperty({ description: '更新时间' })
  @Expose()
  updatedAt: Date;

  @ApiPropertyOptional({
    description: '参与者列表',
    type: [ParticipantResponseDto],
  })
  @Expose()
  @Type(() => ParticipantResponseDto)
  participants?: ParticipantResponseDto[];

  @ApiProperty({ description: '是否已过期' })
  @Expose()
  @Transform(({ obj }) => new Date() > obj.expiresAt)
  isExpired: boolean;

  @ApiProperty({ description: '是否已满员' })
  @Expose()
  @Transform(({ obj }) => obj.currentParticipants >= obj.maxParticipants)
  isFull: boolean;

  @ApiProperty({ description: '是否活跃' })
  @Expose()
  @Transform(
    ({ obj }) => obj.status === 'active' && new Date() <= obj.expiresAt,
  )
  isActive: boolean;

  @ApiProperty({ description: '是否可以加入' })
  @Expose()
  @Transform(({ obj }) => {
    const isFull = obj.currentParticipants >= obj.maxParticipants;
    const isExpired = new Date() > obj.expiresAt;
    return !isFull && !isExpired && obj.status !== 'ended';
  })
  canJoin: boolean;

  @ApiProperty({ description: '房间链接' })
  @Expose()
  @Transform(
    ({ obj }) =>
      `${process.env.FRONTEND_URL || 'http://localhost:3000'}/room/${obj.id}`,
  )
  roomUrl: string;

  // 隐藏敏感信息
  @Exclude()
  creatorIp: string;

  @Exclude()
  passwordHash?: string;

  @Exclude()
  metadata?: any;
}

export class CreateRoomResponseDto extends RoomResponseDto {
  @ApiProperty({ description: '房间访问令牌' })
  @Expose()
  accessToken: string;

  @ApiProperty({ description: '房间链接（包含令牌）' })
  @Expose()
  @Transform(({ obj }) => {
    const baseUrl = process.env.FRONTEND_URL || 'http://localhost:3000';
    return `${baseUrl}/room/${obj.id}?token=${obj.accessToken}`;
  })
  roomUrlWithToken: string;
}

export class JoinRoomResponseDto {
  @ApiProperty({ description: '房间信息', type: RoomResponseDto })
  @Expose()
  @Type(() => RoomResponseDto)
  room: RoomResponseDto;

  @ApiProperty({ description: '参与者信息', type: ParticipantResponseDto })
  @Expose()
  @Type(() => ParticipantResponseDto)
  participant: ParticipantResponseDto;

  @ApiProperty({ description: '访问令牌' })
  @Expose()
  accessToken: string;

  @ApiProperty({ description: 'WebSocket连接URL' })
  @Expose()
  @Transform(() => {
    const wsUrl = process.env.WEBSOCKET_URL || 'ws://localhost:3001';
    return wsUrl;
  })
  websocketUrl: string;
}

export class RoomListResponseDto {
  @ApiProperty({ description: '房间列表', type: [RoomResponseDto] })
  @Expose()
  @Type(() => RoomResponseDto)
  rooms: RoomResponseDto[];

  @ApiProperty({ description: '总数量' })
  @Expose()
  total: number;

  @ApiProperty({ description: '当前页码' })
  @Expose()
  page: number;

  @ApiProperty({ description: '每页数量' })
  @Expose()
  limit: number;

  @ApiProperty({ description: '总页数' })
  @Expose()
  @Transform(({ obj }) => Math.ceil(obj.total / obj.limit))
  totalPages: number;

  @ApiProperty({ description: '是否有下一页' })
  @Expose()
  @Transform(({ obj }) => obj.page < Math.ceil(obj.total / obj.limit))
  hasNext: boolean;

  @ApiProperty({ description: '是否有上一页' })
  @Expose()
  @Transform(({ obj }) => obj.page > 1)
  hasPrev: boolean;
}

export class RoomStatsResponseDto {
  @ApiProperty({ description: '总房间数' })
  @Expose()
  totalRooms: number;

  @ApiProperty({ description: '活跃房间数' })
  @Expose()
  activeRooms: number;

  @ApiProperty({ description: '等待中房间数' })
  @Expose()
  waitingRooms: number;

  @ApiProperty({ description: '已结束房间数' })
  @Expose()
  endedRooms: number;

  @ApiProperty({ description: '总参与者数' })
  @Expose()
  totalParticipants: number;

  @ApiProperty({ description: '在线参与者数' })
  @Expose()
  onlineParticipants: number;

  @ApiProperty({ description: '平均房间持续时间（分钟）' })
  @Expose()
  averageRoomDuration: number;

  @ApiProperty({ description: '统计时间' })
  @Expose()
  timestamp: Date;
}
